﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using StyleMVVM.Logging;
using StyleMVVM.View;
#if !DOT_NET
using Windows.System.Threading;
using Windows.UI.Core;
#else
using System.Threading;
#endif
#if NETFX_CORE
using Windows.UI.Xaml;

#else
using System.Windows;
using System.Windows.Controls;

#endif

namespace StyleMVVM.Messenger
{
	internal class ReferenceMessageHandlerWrapper : IMessageHandlerWrapper
	{
		private readonly Delegate handler;

		public ReferenceMessageHandlerWrapper(Delegate handler, bool background)
		{
			Background = background;

			this.handler = handler;
		}

		public bool Background { get; private set; }

		public bool IsAlive
		{
			get { return true; }
		}

		public object Target
		{
			get { return handler.Target; }
		}

		public MethodInfo Method
		{
			get { return handler.GetMethodInfo(); }
		}

		public bool Execute(object message)
		{
			if (!Background)
			{
				var dispatcher = ViewHelper.MainDispatcher;

#if NETFX_CORE

				if (dispatcher != null &&
				    !dispatcher.HasThreadAccess)
				{
					Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
					                                   () =>
						                                   {
							                                   try
							                                   {
								                                   handler.DynamicInvoke(message);
							                                   }
							                                   catch (Exception exp)
							                                   {
								                                   Logger.Error(
									                                   "Exception thrown while executing message async on dispatcher handler",
									                                   GetType().FullName,
									                                   exp);
							                                   }
						                                   });
				}

#elif WINDOWS_PHONE

				if (dispatcher != null && !dispatcher.CheckAccess())
				{
					dispatcher.BeginInvoke(
						() =>
							{
								try
								{
									handler.DynamicInvoke(message);
								}
								catch (Exception exp)
								{
									Logger.Error(
										"Exception thrown while executing message async on dispatcher handler", GetType().FullName, exp);
								}
							});
				}

#elif DOT_NET
				if (dispatcher != null && !dispatcher.CheckAccess())
				{
					dispatcher.BeginInvoke(new Action(
						                       () =>
							                       {
								                       try
								                       {
									                       handler.DynamicInvoke(message);
								                       }
								                       catch (Exception exp)
								                       {
									                       Logger.Error(
										                       "Exception thrown while executing message async on dispatcher handler",
										                       GetType().FullName,
										                       exp);
								                       }
							                       }));
				}
#endif

				else
				{
					try
					{
						handler.DynamicInvoke(message);
					}
					catch (Exception exp)
					{
						Logger.Error(
							"Exception thrown while executing message on dispatcher handler", GetType().FullName, exp);
					}
				}
			}
			else
			{
#if DOT_NET
				ThreadPool.QueueUserWorkItem(
					(x) =>
						{
							try
							{
								handler.DynamicInvoke(message);
							}
							catch (Exception exp)
							{
								Logger.Error(
									"Exception thrown while executing message in background handler", GetType().FullName, exp);
							}
						});
#else
				ThreadPool.RunAsync(
					(x) =>
						{
							try
							{
								handler.DynamicInvoke(message);
							}
							catch (Exception exp)
							{
								Logger.Error(
									"Exception thrown while executing message in background handler", GetType().FullName, exp);
							}
						});
#endif
			}

			return true;
		}
	}
}